import os
import shutil
import yaml
import shlex
import subprocess as sp

from PySide2.QtCore import QStringListModel
from PySide2.QtWidgets import *
from PySide2.QtGui import QFont

from CustWidgets import PasswordDialog


class OpenDataStreamDialog(QDialog):

    def __init__(self, parent=None, eii_home=None, config=None):
        super(OpenDataStreamDialog, self).__init__(parent=parent)
        self.eii_home = eii_home
        self.config = config
        self.eii_dep_workspace = os.path.join(eii_home, "eii_helper", "workspace")

        # Get data stream list
        self.ds_list = sorted(os.listdir(self.eii_dep_workspace))

        # EII version
        eii_version = self._get_eii_version()
        self.EII_VERSION = eii_version if eii_version else "2.6"

        self.init_ui()
        self.signals_collector()

    def init_ui(self):
        self.setWindowTitle("Open Existed Data Stream")
        self.resize(500, 220)
        self.grid_lyt_global = QGridLayout(self)

        # Font for tips
        title_font = QFont()
        title_font.setPointSize(12)
        title_font.setBold(True)
        title_font.setItalic(True)
        title_font.setWeight(75)

        if not self.ds_list:
            # No Data Stream
            self.no_ds_hint = QLabel(self)
            self.no_ds_hint.setText("No Existed Data Stream")
            self.no_ds_hint.setFont(title_font)
            self.grid_lyt_global.addWidget(self.no_ds_hint, 0, 0, 1, 5)

            # Cancel button
            self.btn_cancel = QPushButton(self)
            self.btn_cancel.setText("&Cancel")
            self.grid_lyt_global.addWidget(self.btn_cancel, 4, 2, 1, 1)
        else:
            # Select Data Stream
            self.lbl_working_dir = QLabel(self)
            self.lbl_working_dir.setText("Select Data Stream")
            self.lbl_working_dir.setFont(title_font)
            self.grid_lyt_global.addWidget(self.lbl_working_dir, 0, 0, 1, 5)

            # Widget for existed data stream
            self.ds_list_view = QListView()
            self.slm = QStringListModel()
            self.slm.setStringList(self.ds_list)
            self.ds_list_view.setModel(self.slm)
            self.grid_lyt_global.addWidget(self.ds_list_view, 1, 0, 1, 5)

            # Delete button
            self.btn_delete = QPushButton(self)
            self.btn_delete.setText("&Delete")
            self.grid_lyt_global.addWidget(self.btn_delete, 4, 1, 1, 1)
            # Cancel button
            self.btn_cancel = QPushButton(self)
            self.btn_cancel.setText("&Cancel")
            self.grid_lyt_global.addWidget(self.btn_cancel, 4, 2, 1, 1)
            # Next button
            self.btn_next = QPushButton(self)
            self.btn_next.setText("&Next")
            self.btn_next.setDefault(True)
            self.btn_next.setAutoDefault(True)
            self.grid_lyt_global.addWidget(self.btn_next, 4, 3, 1, 1)

    def _show_msg_dialog(self, text):
        QMessageBox.warning(self, "Warning", "{}".format(text), QMessageBox.Ok)

    def _refresh_ds_list_view(self):
        self.slm.setStringList(self.ds_list)
        self.ds_list_view.setModel(self.slm)

    def slot_btn_delete(self):
        ds_index = self.ds_list_view.currentIndex().row()
        ds_name = self.ds_list[ds_index]

        # Confirm delection
        res = QMessageBox.warning(self, "Warning", 
            "Are you sure to delete the data stream: \"{}\"?".format(ds_name), 
            QMessageBox.Ok|QMessageBox.Cancel)
        if res == QMessageBox.Cancel:
            return
        
        # Remove from list and reflash UI
        del self.ds_list[ds_index]
        self._refresh_ds_list_view()

        # Remove docker images
        cmd = "docker images | grep {} | awk '{{print $1}}'".format(ds_name)
        result = sp.check_output(cmd, shell=True)
        img_list = shlex.split(result.decode('utf-8'))
        if img_list:
            img_tag_list = []
            for name in img_list:
                name = name + ":" + self.EII_VERSION
                img_tag_list.append(name)
            rm_cmd = ["docker", "rmi", "-f"] + img_tag_list
            sp.Popen(rm_cmd, shell=False)
        
        # Delete data stream dir
        ds_path = os.path.join(self.eii_home, "eii_helper", "workspace", ds_name)
        shutil.rmtree(ds_path)

    def slot_btn_next(self):
        ds_index = self.ds_list_view.currentIndex().row()
        if ds_index == -1:
            self._show_msg_dialog("No existing data stream was found, please create a new one.")
            return
        ds_name = self.ds_list[ds_index]

        # Get user password
        tmp = {}
        pwd_dialog = PasswordDialog(config=tmp)
        pwd_dialog.show()
        pwd_dialog.exec_()
        if "pwd" not in tmp.keys():
            return
        pwd = tmp["pwd"]

        # Update config
        self.config["eii_home"] = self.eii_home
        self.config["project_name"] = ds_name
        self.config["host_pwd"] = pwd

        self.close()

    def signals_collector(self):
        self.btn_delete.clicked.connect(self.slot_btn_delete)
        self.btn_cancel.clicked.connect(self.close)
        self.btn_next.clicked.connect(self.slot_btn_next)
    
    def _get_eii_version(self):
        try:
            env_file = os.path.join(self.eii_home, "build", ".env")
            with open(env_file, "r") as f:
                lines = f.readlines()
                for line in lines:
                    if "EII_VERSION" in line:
                        version = line.strip().split("=")[-1]
                        return version
        except:
            return ""
